<?php

/**
 * 合同收入信息仓库
 * @author wangwx 2015-5-11
 */

namespace common\repositories\myhtsq;

use common\entities\myhtsq\ContractPropertyEntity;
use common\repositories\BaseRepository;
use common\repositories\common\MyscrmContractRepository;
use common\repositories\common\MyscrmContractSyncDeleteDataRepository;
use common\services\common\MyscrmContractApplicationService;
use common\support\StringHelper;
use common\support\Helper;
use common\entities\myhtsq\ContractRevenueEntity;
use yii\db\Query;
use common\entities\myhtsq\ContractReceivableEntity;
use common\services\myhtsq\ErpInterfaceService;
use common\services\myhtsq\ContractService;
use common\entities\ContractEntity;
use common\models\myhtsq\ContractApiLogModel;
use common\repositories\myhtsq\ContractManageRepository;
use common\error\ErrorCode;


class ContractRevenueRepository extends BaseRepository
{

    const YK_VALUE_ADDED_SERVICES_REVENUE = "云客租用服务收入项"; //本期待确认收入
    const YK_RENT_SERVICES_REVENUE = "云客增值服务收入项";//本期已确认收入
    const YK_INTERNET_SERVICES_REVENUE = "云客互联网服务收入项";//本期已确认收入

    /**
     * 构造方法
     * @param unknown $config (optional)
     */
    public function __construct($config = [])
    {
        parent::__construct($config);
    }

    /**
     * 根据合同id,获取收入信息
     * @param string $contractId 合同id
     * @return array
     */
    public static function getContractRevenueListByContractId($contractId)
    {
        $query = new Query();
        $data = $query->from('myscrm_contract_revenue')->select('myscrm_buss_account_types.type_name,myscrm_buss_account_types.finance_type_name,myscrm_contract_revenue.*')->leftJoin('myscrm_buss_account_types', 'myscrm_buss_account_types.type_id=myscrm_contract_revenue.revenue_type')->where(['myscrm_contract_revenue.contract_id' => $contractId])->all(ContractReceivableEntity::getDb());
        return $data;
    }

    /**
     * 根据合同id,获取收入信息
     * @param string $contractId 合同id
     * @return array
     */
    public static function getContractRevenueListByRevenueId($revenueId)
    {
        $query = new Query();
        return $query->from('myscrm_contract_revenue')
            ->select('myscrm_buss_account_types.type_name,myscrm_buss_account_types.finance_type_name,myscrm_contract_revenue.*')
            ->leftJoin('myscrm_buss_account_types', 'myscrm_buss_account_types.type_id=myscrm_contract_revenue.revenue_type')
            ->where(['myscrm_contract_revenue.revenue_id' => $revenueId])
            ->all(ContractReceivableEntity::getDb());

    }


    /**
     * 根据合同begin_on,end_on,establish_time,获取收入信息
     * @param string $beginOn ,$endOn,$establishTime
     * @return array
     */
    public static function getContractRevenueByTime($contractId, $beginOn, $endOn, $establishTime)
    {
        $query = new Query();
        $data = $query->from('myscrm_contract_revenue')->select('*')->where(['contract_id' => $contractId, 'begin_on' => $beginOn, 'end_on' => $endOn, 'establish_time' => $establishTime,'parent_id'=>''])->one(ContractReceivableEntity::getDb());
        return $data;
    }


    /**
     * @param $contractId
     * @param $beginOn
     * @param $endOn
     * @param $establishTime
     * @param $revenue_type
     * @return array|bool
     */
    public static function getContractRevenueBy($contractId, $beginOn, $endOn, $establishTime,$revenue_type)
    {
        $query = new Query();
        $data = $query->from('myscrm_contract_revenue')->select('*')->where(['contract_id' => $contractId, 'begin_on' => $beginOn, 'end_on' => $endOn, 'establish_time' => $establishTime,'parent_id'=>'','revenue_type'=>$revenue_type])->one(ContractReceivableEntity::getDb());
        return $data;
    }

    /**
     * 根据收入id 删除收入信息
     * @param string $revenueId
     * @return boolean
     */
    public static function deleteContractRevenueByRevenueId($revenueId)
    {
        /** @var MyscrmContractSyncDeleteDataRepository $contractSyncDeleteDataRepository */
        $contractSyncDeleteDataRepository = \Yii::createObject(MyscrmContractSyncDeleteDataRepository::className());

        $findResult = ContractRevenueEntity::findAll(["revenue_id" => $revenueId]);
        $deleteResult = ContractRevenueEntity::deleteAll(["revenue_id" => $revenueId]);

        foreach ($findResult as $single) {
            $before = $single->getAttributes();
            $now = false;
            IncomeItemLogRepository::add($before, $now, $deleteResult, IncomeItemLogRepository::OPERATE_DELETE);
        }

        if ($deleteResult > 0) {
            $contractSyncDeleteDataRepository->add('myscrm_contract_revenue', 'revenue_id', $revenueId);
        }

        return $deleteResult;
    }

    /**
     * 新增收入信息
     * @param $contractRevenueModel
     * @param $contractId
     * @param bool $old_income_code
     * @return bool|string
     * @throws \Exception
     */
    public static function addContractRevenueRecord($contractRevenueModel, $contractId,$old_income_code = false)
    {
        $ykPropertyClassId = [
            ContractPropertyEntity::MYYK_PROPERTY_DIRECTLY_UNDER_ID,//云客签约-直属
            ContractPropertyEntity::MYYK_PROPERTY_JOINT_OPERATION_ID,//云客签约-直属区域
            ContractPropertyEntity::MYYK_PROPERTY_DIRECT_SALES_ID,//云客直销
        ];

        $before = false;
        $contractRevenueEntity = new ContractRevenueEntity();
        $data = $contractRevenueModel->attributes;
        $contractRevenueEntity->load($data, '');
        if(!empty($data['parent_id']) && $old_income_code){
            $contractRevenueModel->income_code = self::getRedFlushIncomeCode($old_income_code, $data['parent_id']);
        }
        $contractRevenueEntity->revenue_id = StringHelper::uuid();
        $contractRevenueEntity->contract_id = $contractId;
        $contractRevenueEntity->income_code = $contractRevenueModel->income_code;
        $contractRevenueEntity->close_status = 1;//新增收入都是待确认
        $contractRevenueEntity->establish_time = $contractRevenueModel->establish_time;
        $contractRevenueEntity->begin_on = $contractRevenueModel->begin_on;
        $contractRevenueEntity->end_on = $contractRevenueModel->end_on;
        $contractRevenueEntity->unrecognized_bad_debt_amount = $contractRevenueModel->unrecognized_bad_debt_amount;
        $contractRevenueEntity->recognized_bad_debt_amount = $contractRevenueModel->recognized_bad_debt_amount;
        $contractRevenueEntity->kingdee_bad_debt_amount = $contractRevenueModel->kingdee_bad_debt_amount;
        $contractRevenueEntity->add_type = 1;
        $now = $contractRevenueEntity ? $contractRevenueEntity->getAttributes() : false;
        $manageEntity = ContractManageRepository::getContractManageModelByContractId($contractId);
        $contract_property_id = $manageEntity->contract_property_id;
        $contract_type = in_array($contract_property_id, $ykPropertyClassId) ? 'yk' : 'ly-hq';
        $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_ADD, $contract_type);
        if (!$check) {
            throw new \Exception('待生成的收入项不满足生成条件');
        }
        if ($contractRevenueEntity->validate() && $contractRevenueEntity->save()) {
            IncomeItemLogRepository::add($before, $now, 1, IncomeItemLogRepository::OPERATE_ADD);
            self::revenueApiLog($contractId, $contractRevenueEntity->revenue_id, __LINE__, __METHOD__, '新增收入');
            return $contractRevenueEntity->revenue_id;
        } else {
            IncomeItemLogRepository::add($before, $now, 0, IncomeItemLogRepository::OPERATE_ADD);
            return false;
        }
    }

    private static function revenueApiLog($contractId, $revenueId, $line, $method, $maintainRemark)
    {
        $contractManage = ContractManageRepository::getContractManageModelByContractId($contractId);
        $userGuid = \Yii::$app->user->identity->userguid;

        libxml_disable_entity_loader(false);
        /** @var ErpInterfaceService $erpInterfaceService */
        $erpInterfaceService = \Yii::createObject(ErpInterfaceService::className());
        $revenueInfo = self::getRevenueByRevenueId($revenueId);

        //明源签约-直属 明源签约-联营 才调用接口
        if (in_array($contractManage->contract_property_id, ['54f8a2b7-fce7-11e4-bed8-00155d02c832', '7f828b1b-fce8-11e4-bed8-00155d02c832'])) {
            $api = $erpInterfaceService->saveRevenue($revenueInfo);
        }

        $api = empty($api) ? '非明源合同' : $api;

        $parameter = $erpInterfaceService->parameterToJson($revenueInfo);
        $contractApiLogModel = new contractApiLogModel();
        $contractApiLogModel->log_type = 2;
        $contractApiLogModel->call_line = $line;
        $contractApiLogModel->call_method = $method;
        $contractApiLogModel->call_parametes = json_encode($parameter, JSON_UNESCAPED_UNICODE);
        $contractApiLogModel->return_data = json_encode($api, JSON_UNESCAPED_UNICODE);
        $contractApiLogModel->return_code = $erpInterfaceService->getErrCode();
        $contractApiLogModel->error_msg = $erpInterfaceService->getErrMsg();
        $contractApiLogModel->call_user = empty($userGuid) ? 'A3C8F32D-374B-4772-95E9-0F3A84F2F1A1' : $userGuid;//孟兵要求 2018-03-29
        $contractApiLogModel->maintain_remark = $maintainRemark;
        ContractApiLogRepository::addContractApiLogRecord($contractApiLogModel);
    }

    /**
     * 根据收入ID删除对应的收入信息
     * @param string $revenueId 收入ID
     * @return boolean 返回true时表示删除成功，否则失败
     */
    public static function deleteRevenue($revenueId)
    {
        /** @var MyscrmContractSyncDeleteDataRepository $contractSyncDeleteDataRepository */
        $contractSyncDeleteDataRepository = \Yii::createObject(MyscrmContractSyncDeleteDataRepository::className());
        $findResult = ContractRevenueEntity::findAll(['revenue_id' => $revenueId]);
        $deleteResult = ContractRevenueEntity::deleteContractRevenueByRevenueId($revenueId);
        foreach ($findResult as $single) {
            $before = $single->getAttributes();
            $now = false;
            IncomeItemLogRepository::add($before, $now, $deleteResult, IncomeItemLogRepository::OPERATE_DELETE);
        }

        if (empty($deleteResult)) {
            return self::setAndReturn(ContractRevenueEntity::getErrCode());
        } else {
            return $contractSyncDeleteDataRepository->add('myscrm_contract_revenue', 'revenue_id', $revenueId);
        }

    }

    /**
     * 新增收入信息
     * @param $arr
     * @param $contractId
     * @param string $contractType
     * @param array $author_infos
     * @param array $myscrm_contract
     * @return bool|mixed
     * @throws \Exception
     */
    public static function updateContractRevenueRecordByEstablish($arr, $contractId, $contractType = '',$myscrm_contract,$author_infos)
    {
//        $contractRevenues = ContractRevenueEntity::find()->where(['contract_id' => $contractId, 'add_type' => 2,'parent_id'=>''])->asArray()->all();
//        $contractRevenueAllByContractId = array_column($contractRevenues, 'revenue_id');


        //TODO 对于修改租期的处理
        if($author_infos && $myscrm_contract){
            foreach ($author_infos as $author_info){
                $ApplicationInfo = MyscrmContractApplicationService::getApplicationInfoByApplicationId($author_info['ApplicationId']);
                $ApplicationInfo = empty($ApplicationInfo)?MyscrmContractApplicationService::getApplicationInfoByApplicationId($author_info['application_info_id']):$ApplicationInfo;
                $buss_type_id = $ApplicationInfo['buss_type_id'];
                $contractRevenueEntity = ContractRevenueEntity::find()->where(['contract_id' => $contractId, 'add_type' => 2, 'establish_time' => $myscrm_contract['PerformanceAccountingTime'], 'begin_on' => $myscrm_contract['BeginOn'], 'end_on' => $myscrm_contract['EndOn'], 'revenue_type' => $buss_type_id,'parent_id'=>''])->one();
                if(empty($contractRevenueEntity)){
                    continue;
                }
//                $contractRevenueEntity->amount = $contractType == 'yk'?$author_info['signAmount']:$author_info['SettlementAmount'];
//                $contractRevenueEntity->amount = 0;
                $current_myscrm_contract = MyscrmContractRepository::getContractByContractId($author_info['Id']);
                $contractRevenueEntity->amount = -($contractType == 'yk'?$current_myscrm_contract['signAmount']:$current_myscrm_contract['SettlementAmount']);
                $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_EDIT, $contractType);
                if ($check === false) {
                    throw new \Exception('待修改的收入项不满足修改条件');
                }
                $old_revenue_id = $contractRevenueEntity->revenue_id;
                $old_income_code = $contractRevenueEntity->income_code;
                $old_revenue_type = $contractRevenueEntity->revenue_type;
                $old_contract_id = $contractRevenueEntity->contract_id;
                $old_begin_on = $contractRevenueEntity->begin_on;
                $old_end_on = $contractRevenueEntity->end_on;
                $old_establish_time = $contractRevenueEntity->establish_time;
                if (is_numeric($check)) {
                    $contractRevenueEntity = new ContractRevenueEntity();
                    //预留关联收入项类型编码
                    $contractRevenueEntity->revenue_id = StringHelper::uuid();
                    $contractRevenueEntity->created_by = $_SESSION['__id'];
                    $contractRevenueEntity->created_on = date('Y-m-d H:i:s');
                    $contractRevenueEntity->contract_id = $old_contract_id;
                    $contractRevenueEntity->amount = $check;
                    $contractRevenueEntity->begin_on = $old_begin_on;//租期开始时间
                    $contractRevenueEntity->end_on = $old_end_on;//租期结束时间
                    //$contractRevenueEntity->establish_time = $item['EstablishTime'];//开通时间
                    $contractRevenueEntity->establish_time = $old_establish_time;//开通时间
                    $contractRevenueEntity->revenue_type = $old_revenue_type;//
                    $contractRevenueEntity->income_code = self::getRedFlushIncomeCode($old_income_code, $old_revenue_id);
                    $contractRevenueEntity->add_type = 2;//标识为通过开通信息推送产生
                    $contractRevenueEntity->maintain_remark = '修改时间自动红冲';//标识为通过开通信息推送产生
                    $contractRevenueEntity->parent_id = $old_revenue_id;//补哪个收入的缺

                    $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_ADD, $contractType);
                    if (!$check) {
                        throw new \Exception('待生成的收入项不满足生成条件');
                    }
                    if ($contractRevenueEntity->amount != 0 && $contractRevenueEntity->validate()) {
                        $res = $contractRevenueEntity->save();
                        $results[] = $res;
                        $before = false;
                        $now = $contractRevenueEntity->getAttributes();
                        IncomeItemLogRepository::add($before, $now, $res, IncomeItemLogRepository::OPERATE_ADD);
                        //api调用日志
                        self::revenueApiLog($contractId, $contractRevenueEntity->revenue_id, __LINE__, __METHOD__, '新增收入');
                    } elseif ($contractRevenueEntity->amount == 0) {
                        $results[] = true;
                    }
                }
            }
        }

        $results = [];
        $revenue_ids = [];
        foreach ($arr as $item) {
            $contractRevenueEntity = ContractRevenueEntity::find()->where(['contract_id' => $contractId, 'add_type' => 2, 'establish_time' => $item['PerformanceAccountingTime'], 'begin_on' => $item['BeginOn'], 'end_on' => $item['EndOn'], 'revenue_type' => $item['buss_type_id'],'parent_id'=>''])->one();
            if (!empty($contractRevenueEntity)) {

                $contractRevenueEntity->amount = $contractType == 'yk' ? $item['signAmount'] : $item['summaryReceived'];//理论上有这条记录就只需改钱
                //要删除该合同下没有通过三个条件匹配到的那条记录或者修订汇总金额变成0
                $revenue_ids[] = $contractRevenueEntity->revenue_id;

                $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_EDIT, $contractType);
                if ($check === false) {
                    throw new \Exception('待修改的收入项不满足修改条件');
                }

                $old_revenue_id = $contractRevenueEntity->revenue_id;
                $old_income_code = $contractRevenueEntity->income_code;
                if (is_numeric($check)) {
                    $contractRevenueEntity = new ContractRevenueEntity();
                    //预留关联收入项类型编码
                    $contractRevenueEntity->revenue_id = StringHelper::uuid();
                    $contractRevenueEntity->created_by = $_SESSION['__id'];
                    $contractRevenueEntity->created_on = date('Y-m-d H:i:s');
                    $contractRevenueEntity->contract_id = $contractId;
                    $contractRevenueEntity->amount = $check;
                    $contractRevenueEntity->begin_on = $item['BeginOn'];//租期开始时间
                    $contractRevenueEntity->end_on = $item['EndOn'];//租期结束时间
                    $contractRevenueEntity->establish_time = $item['PerformanceAccountingTime'];//开通时间
                    $contractRevenueEntity->revenue_type = $item['buss_type_id'];//
                    $contractRevenueEntity->income_code = self::getRedFlushIncomeCode($old_income_code, $old_revenue_id);
                    $contractRevenueEntity->add_type = 2;//标识为通过开通信息推送产生
                    $contractRevenueEntity->maintain_remark = '修改金额自动红冲';//标识为通过开通信息推送产生
                    $contractRevenueEntity->parent_id = $old_revenue_id;//补哪个收入的缺

                    $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_ADD, $contractType);
                    if (!$check) {
                        throw new \Exception('待生成的收入项不满足生成条件');
                    }
                    if ($contractRevenueEntity->amount != 0) {
                        $res = $contractRevenueEntity->save();
                        $results[] = $res;
                        $before = false;
                        $now = $contractRevenueEntity->getAttributes();
                        IncomeItemLogRepository::add($before, $now, $res, IncomeItemLogRepository::OPERATE_ADD);
                        //api调用日志
                        self::revenueApiLog($contractId, $contractRevenueEntity->revenue_id, __LINE__, __METHOD__, '新增收入');
                    } elseif ($contractRevenueEntity->amount == 0) {
                        $results[] = true;
                    }
                } else {
                    //TODO 2018-07-23 收入项不允许修改
//                    $now = $contractRevenueEntity->getAttributes();
//                    $res = $contractRevenueEntity->save();
//                    $results[] = $res;
//                    IncomeItemLogRepository::add($before,$now,$res,IncomeItemLogRepository::OPERATE_EDIT);
//                    //api调用日志
//                    self::revenueApiLog($contractId,$contractRevenueEntity->revenue_id,__LINE__,__METHOD__,'修改收入');
                }
            } else {
                $contractRevenueEntity = new ContractRevenueEntity();
                //预留关联收入项类型编码
                $contractRevenueEntity->revenue_id = StringHelper::uuid();
                $contractRevenueEntity->created_by = $_SESSION['__id'];
                $contractRevenueEntity->created_on = date('Y-m-d H:i:s');
                $contractRevenueEntity->contract_id = $contractId;
                $contractRevenueEntity->amount = $contractType == 'yk' ? $item['signAmount'] : $item['summaryReceived'];//理论上有这条记录就只需改钱
                $contractRevenueEntity->begin_on = $item['BeginOn'];//租期开始时间
                $contractRevenueEntity->end_on = $item['EndOn'];//租期结束时间
                $contractRevenueEntity->establish_time = $item['PerformanceAccountingTime'];//开通时间
                $contractRevenueEntity->revenue_type = $item['buss_type_id'];//
                $contractRevenueEntity->income_code = $item['income_code'];
                $contractRevenueEntity->add_type = 2;//标识为通过开通信息推送产生
                $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_ADD, $contractType);
                if (!$check) {
                    throw new \Exception('待生成的收入项不满足生成条件');
                }
                if ($contractRevenueEntity->amount != 0) {
                    $res = $contractRevenueEntity->save();
                    $results[] = $res;
                    $before = false;
                    $now = $contractRevenueEntity->getAttributes();
                    IncomeItemLogRepository::add($before, $now, $res, IncomeItemLogRepository::OPERATE_ADD);
                    //api调用日志
                    self::revenueApiLog($contractId, $contractRevenueEntity->revenue_id, __LINE__, __METHOD__, '新增收入');
                } elseif ($contractRevenueEntity->amount == 0) {
                    $results[] = true;
                }
            }
        }

//        $diffRevenue_ids = array_diff($contractRevenueAllByContractId, $revenue_ids);
//
//        foreach ($diffRevenue_ids as $id) {
//            $contractRevenueEntity = ContractRevenueEntity::find()->where(['revenue_id' => $id, 'add_type' => 2])->one();
//            $before = $contractRevenueEntity ? $contractRevenueEntity->getAttributes() : false;
//            $contractRevenueEntity->amount = 0;//理论上有这条记录就只需改钱
//            $now = $contractRevenueEntity->getAttributes();
//            $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_EDIT, $contractType);
//            if ($check === false) {
//                throw new \Exception('待修改的收入项不满足修改条件');
//            }
//            $old_revenue_id = $contractRevenueEntity->revenue_id;
//            $old_income_code = $contractRevenueEntity->income_code;
//            $old_revenue_type = $contractRevenueEntity->revenue_type;
//            if (is_numeric($check)) {
//                $contractRevenueEntity = new ContractRevenueEntity();
//                //预留关联收入项类型编码
//                $contractRevenueEntity->revenue_id = StringHelper::uuid();
//                $contractRevenueEntity->created_by = $_SESSION['__id'];
//                $contractRevenueEntity->created_on = date('Y-m-d H:i:s');
//                $contractRevenueEntity->contract_id = $contractRevenueEntity->contract_id;
//                $contractRevenueEntity->amount = $check;
//                $contractRevenueEntity->begin_on = $contractRevenueEntity->begin_on;//租期开始时间
//                $contractRevenueEntity->end_on = $contractRevenueEntity->end_on;//租期结束时间
//                //$contractRevenueEntity->establish_time = $item['EstablishTime'];//开通时间
//                $contractRevenueEntity->establish_time = $contractRevenueEntity->establish_time;//开通时间
//                $contractRevenueEntity->revenue_type = $old_revenue_type;//
//                $contractRevenueEntity->income_code = self::getRedFlushIncomeCode($old_income_code, $old_revenue_id);
//                $contractRevenueEntity->add_type = 2;//标识为通过开通信息推送产生
//                $contractRevenueEntity->maintain_remark = '自动红冲';//标识为通过开通信息推送产生
//                $contractRevenueEntity->parent_id = $old_revenue_id;//补哪个收入的缺
//                $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_ADD, $contractType);
//                if (!$check) {
//                    throw new \Exception('待生成的收入项不满足生成条件');
//                }
//                if ($contractRevenueEntity->amount != 0) {
//                    $res = $contractRevenueEntity->save();
//                    $results[] = $res;
//                    $before = false;
//                    $now = $contractRevenueEntity->getAttributes();
//                    IncomeItemLogRepository::add($before, $now, $res, IncomeItemLogRepository::OPERATE_ADD);
//                    //api调用日志
//                    self::revenueApiLog($contractId, $contractRevenueEntity->revenue_id, __LINE__, __METHOD__, '新增收入');
//                } elseif ($contractRevenueEntity->amount == 0) {
//                    $results[] = true;
//                }
//            } else {
//                //TODO 删除结算金额为0的收入项
////                $res = $contractRevenueEntity->delete();
////                $results[] = $res;
////                IncomeItemLogRepository::add($before,$now,$res,IncomeItemLogRepository::OPERATE_EDIT);
//            }
//        }

        $result = false;
        foreach ($results as $val) {
            $result = $val;
            if ($val === false) {//有一次出现失败就表示失败了
                $result = false;
                break;
            }

        }

        return $result;
    }


    public static function updateContractRevenueByRedFlush($arr, $contractId, $contractType = '',$revenue){
        $contractRevenues = ContractRevenueEntity::find()->where(['contract_id' => $contractId, 'add_type' => 2,'parent_id'=>''])->asArray()->all();
        $contractRevenueAllByContractId = array_column($contractRevenues, 'revenue_id');
        $results = [];
        foreach ($arr as $item) {
            $contractRevenueEntity = ContractRevenueEntity::find()->where(['contract_id' => $contractId, 'add_type' => 2, 'establish_time' => $item['PerformanceAccountingTime'], 'begin_on' => $item['BeginOn'], 'end_on' => $item['EndOn'], 'revenue_type' => $item['buss_type_id'],'parent_id'=>''])->one();
            if($contractRevenueEntity->revenue_id == $revenue['revenue_id']){
                $contractRevenueEntity->amount = $contractType == 'yk' ? $item['signAmount'] : $item['summaryReceived'];//理论上有这条记录就只需改钱
                $contractRevenueEntity->modified_by = $_SESSION['__id'];
                $contractRevenueEntity->modified_on = date('Y-m-d H:i:s');//修改时间
                $contractRevenueEntity->begin_on = $item['BeginOn'];//租期开始时间
                $contractRevenueEntity->end_on = $item['EndOn'];//租期结束时间
                //$contractRevenueEntity->establish_time = $item['EstablishTime'];//开通时间
                $contractRevenueEntity->establish_time = $item['PerformanceAccountingTime'];//开通时间
                $contractRevenueEntity->revenue_type = $item['buss_type_id'];//

                //要删除该合同下没有通过三个条件匹配到的那条记录或者修订汇总金额变成0
                $revenue_ids[] = $contractRevenueEntity->revenue_id;

                $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_EDIT, $contractType);
                if ($check === false) {
                    throw new \Exception('待修改的收入项不满足修改条件');
                }
                $old_revenue_id = $contractRevenueEntity->revenue_id;
                $old_income_code = $contractRevenueEntity->income_code;
                if (is_numeric($check)) {
                    $contractRevenueEntity = new ContractRevenueEntity();
                    //预留关联收入项类型编码
                    $contractRevenueEntity->revenue_id = StringHelper::uuid();
                    $contractRevenueEntity->created_by = $_SESSION['__id'];
                    $contractRevenueEntity->created_on = date('Y-m-d H:i:s');
                    $contractRevenueEntity->contract_id = $contractId;
                    $contractRevenueEntity->amount = $check;
                    $contractRevenueEntity->begin_on = $item['BeginOn'];//租期开始时间
                    $contractRevenueEntity->end_on = $item['EndOn'];//租期结束时间
                    //$contractRevenueEntity->establish_time = $item['EstablishTime'];//开通时间
                    $contractRevenueEntity->establish_time = $item['PerformanceAccountingTime'];//开通时间
                    $contractRevenueEntity->revenue_type = $item['buss_type_id'];//
                    $contractRevenueEntity->income_code = self::getRedFlushIncomeCode($old_income_code, $old_revenue_id);
                    $contractRevenueEntity->add_type = 2;//标识为通过开通信息推送产生
                    $contractRevenueEntity->maintain_remark = '自动红冲';//标识为通过开通信息推送产生
                    $contractRevenueEntity->parent_id = $old_revenue_id;//补哪个收入的缺

                    $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_ADD, $contractType);
                    if (!$check) {
                        throw new \Exception('待生成的收入项不满足生成条件');
                    }

                    if ($contractRevenueEntity->amount != 0) {
                        $res = $contractRevenueEntity->save();
                        $results[] = $res;
                        $before = false;
                        $now = $contractRevenueEntity->getAttributes();
                        IncomeItemLogRepository::add($before, $now, $res, IncomeItemLogRepository::OPERATE_ADD);
                        //api调用日志
                        self::revenueApiLog($contractId, $contractRevenueEntity->revenue_id, __LINE__, __METHOD__, '新增收入');
                    } elseif ($contractRevenueEntity->amount == 0) {
                        $results[] = true;
                    }
                } else {
                      //TODO 2018-07-23 收入项不允许修改
//                    $now = $contractRevenueEntity->getAttributes();
//                    $res = $contractRevenueEntity->save();
//                    $results[] = $res;
//                    IncomeItemLogRepository::add($before,$now,$res,IncomeItemLogRepository::OPERATE_EDIT);
//                    //api调用日志
//                    self::revenueApiLog($contractId,$contractRevenueEntity->revenue_id,__LINE__,__METHOD__,'修改收入');
                }
            }

            if(empty($contractRevenueEntity)){
                $contractRevenueEntity = new ContractRevenueEntity();
                //预留关联收入项类型编码
                $contractRevenueEntity->revenue_id = StringHelper::uuid();
                $contractRevenueEntity->created_by = $_SESSION['__id'];
                $contractRevenueEntity->created_on = date('Y-m-d H:i:s');
                $contractRevenueEntity->contract_id = $contractId;
                $contractRevenueEntity->amount = $contractType == 'yk' ? $item['signAmount'] : $item['summaryReceived'];//理论上有这条记录就只需改钱
                $contractRevenueEntity->begin_on = $item['BeginOn'];//租期开始时间
                $contractRevenueEntity->end_on = $item['EndOn'];//租期结束时间
                //$contractRevenueEntity->establish_time = $item['EstablishTime'];//开通时间
                $contractRevenueEntity->establish_time = $item['PerformanceAccountingTime'];//开通时间
                $contractRevenueEntity->revenue_type = $item['buss_type_id'];//
                $contractRevenueEntity->income_code = $item['income_code'];
                $contractRevenueEntity->add_type = 2;//标识为通过开通信息推送产生

                $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_ADD, $contractType);
                if (!$check) {
                    throw new \Exception('待生成的收入项不满足生成条件');
                }
                if ($contractRevenueEntity->amount != 0) {
                    $res = $contractRevenueEntity->save();
                    $results[] = $res;
                    $before = false;
                    $now = $contractRevenueEntity->getAttributes();
                    IncomeItemLogRepository::add($before, $now, $res, IncomeItemLogRepository::OPERATE_ADD);
                    //api调用日志
                    self::revenueApiLog($contractId, $contractRevenueEntity->revenue_id, __LINE__, __METHOD__, '新增收入');
                } elseif ($contractRevenueEntity->amount == 0) {
                    $results[] = true;
                }
            }
        }


        $diffRevenue_ids = array_diff($contractRevenueAllByContractId, $revenue_ids);

        foreach ($diffRevenue_ids as $id) {
            $contractRevenueEntity = ContractRevenueEntity::find()->where(['revenue_id' => $id, 'add_type' => 2])->one();
            $before = $contractRevenueEntity ? $contractRevenueEntity->getAttributes() : false;
            $contractRevenueEntity->amount = 0;//理论上有这条记录就只需改钱
            $now = $contractRevenueEntity->getAttributes();
            $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_EDIT, $contractType);
            if ($check === false) {
                throw new \Exception('待修改的收入项不满足修改条件');
            }
            $old_revenue_id = $contractRevenueEntity->revenue_id;
            $old_income_code = $contractRevenueEntity->income_code;
            $old_revenue_type = $contractRevenueEntity->revenue_type;
            $old_begin_on = $contractRevenueEntity->begin_on;
            $old_end_on = $contractRevenueEntity->end_on;
            $old_establish_time = $contractRevenueEntity->establish_time;
            if (is_numeric($check)) {
                $contractRevenueEntity = new ContractRevenueEntity();
                //预留关联收入项类型编码
                $contractRevenueEntity->revenue_id = StringHelper::uuid();
                $contractRevenueEntity->created_by = $_SESSION['__id'];
                $contractRevenueEntity->created_on = date('Y-m-d H:i:s');
                $contractRevenueEntity->contract_id = $contractId;
                $contractRevenueEntity->amount = $check;
                $contractRevenueEntity->begin_on = $old_begin_on;//租期开始时间
                $contractRevenueEntity->end_on = $old_end_on;//租期结束时间
                //$contractRevenueEntity->establish_time = $item['EstablishTime'];//开通时间
                $contractRevenueEntity->establish_time = $old_establish_time;//开通时间
                $contractRevenueEntity->revenue_type = $old_revenue_type;//
                $contractRevenueEntity->income_code = self::getRedFlushIncomeCode($old_income_code, $old_revenue_id);
                $contractRevenueEntity->add_type = 2;//标识为通过开通信息推送产生
                $contractRevenueEntity->maintain_remark = '自动红冲';//标识为通过开通信息推送产生
                $contractRevenueEntity->parent_id = $old_revenue_id;//补哪个收入的缺
                $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_ADD, $contractType);
                if (!$check) {
                    throw new \Exception('待生成的收入项不满足生成条件');
                }
                if ($contractRevenueEntity->amount != 0) {
                    $res = $contractRevenueEntity->save();
                    $results[] = $res;
                    $before = false;
                    $now = $contractRevenueEntity->getAttributes();
                    IncomeItemLogRepository::add($before, $now, $res, IncomeItemLogRepository::OPERATE_ADD);
                    //api调用日志
                    self::revenueApiLog($contractId, $contractRevenueEntity->revenue_id, __LINE__, __METHOD__, '新增收入');
                } elseif ($contractRevenueEntity->amount == 0) {
                    $results[] = true;
                }
            } else {
                //TODO 删除结算金额为0的收入项
//                $res = $contractRevenueEntity->delete();
//                $results[] = $res;
//                IncomeItemLogRepository::add($before,$now,$res,IncomeItemLogRepository::OPERATE_EDIT);
            }
        }

        $result = false;
        foreach ($results as $val) {
            $result = $val;
            if ($val === false) {//有一次出现失败就表示失败了
                $result = false;
                break;
            }

        }

        return $result;
    }


    public static function getRedFlushIncomeCode($income_code, $revenue_id)
    {
        $total_red_flush = ContractRevenueEntity::find()->where(['parent_id' => $revenue_id])->count('*');
        return $income_code . '-RF-' . ($total_red_flush + 1);
    }


    /**
     * 更收入信息
     * @param common\models\myhtsq\ContractRevenueModel $contractRevenueModel 前端模型
     * @return boolean
     */
    public static function updateContractRevenueRecord($contractRevenueModel)
    {

        $ykPropertyClassId = [
            ContractPropertyEntity::MYYK_PROPERTY_DIRECTLY_UNDER_ID,//云客签约-直属
            ContractPropertyEntity::MYYK_PROPERTY_JOINT_OPERATION_ID,//云客签约-直属区域
            ContractPropertyEntity::MYYK_PROPERTY_DIRECT_SALES_ID,//云客直销
        ];


        $contractRevenueEntity = new ContractRevenueEntity();
        $contractModelInfo = $contractRevenueEntity::find()->where(['revenue_id' => $contractRevenueModel->revenue_id])->one();
        $before = $contractModelInfo ? $contractModelInfo->getAttributes() : false;
        if ($contractRevenueModel->recognition_status !== "recognized") {
            $contractModelInfo->amount = $contractRevenueModel->amount;
        }

        $contractModelInfo->unrecognized_bad_debt_amount = $contractRevenueModel->unrecognized_bad_debt_amount;
        $contractModelInfo->recognized_bad_debt_amount = $contractRevenueModel->recognized_bad_debt_amount;
        $contractModelInfo->kingdee_bad_debt_amount = $contractRevenueModel->kingdee_bad_debt_amount;
        $contractModelInfo->establish_time = $contractRevenueModel->establish_time;
        $contractModelInfo->begin_on = $contractRevenueModel->begin_on;
        $contractModelInfo->end_on = $contractRevenueModel->end_on;
        if (!empty($contractRevenueModel->closeStatus)) {
            $contractModelInfo->close_status = $contractRevenueModel->closeStatus;
        }


        $manageEntity = ContractManageRepository::getContractManageModelByContractId($contractModelInfo->contract_id);
        $contract_property_id = $manageEntity->contract_property_id;
        $contract_type = in_array($contract_property_id, $ykPropertyClassId) ? 'yk' : 'ly-hq';
        $check = $contractRevenueEntity->generateCheck(ContractRevenueEntity::OPERATE_EDIT, $contract_type);
        if (!$check) {
            throw new \Exception('待修改的收入项不满足修改条件');
        }
        $now = $contractModelInfo->getAttributes();
        if ($contractModelInfo->validate() && $contractModelInfo->save()) {
            IncomeItemLogRepository::add($before, $now, 1, IncomeItemLogRepository::OPERATE_EDIT);
            self::revenueApiLog($contractModelInfo->contract_id, $contractModelInfo->revenue_id, __LINE__, __METHOD__, '修改收入');
            return $contractModelInfo->revenue_id;
        } else {
            IncomeItemLogRepository::add($before, $now, 0, IncomeItemLogRepository::OPERATE_EDIT);
            return false;
        }
    }

    /**
     * 根据合同id,获取合同收入金额总额
     * @param string $contractId 合同id
     * @return float
     */
    public static function getContractRevenueSumByContractId($contractId)
    {
        return ContractRevenueEntity::find()->where(['contract_id' => $contractId])->sum('amount');
    }

    public static function getParentRevenueSum($revenue_id)
    {
        $res = ContractRevenueEntity::find()->where(['revenue_id' => $revenue_id])->sum('amount');
        return $res?$res:0;
    }

    /**
     * 获取红冲总金额
     * @param $revenue_id
     * @return mixed
     */
    public static function getRevenueRedFlushSum($revenue_id)
    {
        $res = ContractRevenueEntity::find()->where(['parent_id' => $revenue_id])->sum('amount');
        return $res?$res:0;
    }

    /**
     * 根据合同id,获取合同收入金额总额
     * @param string $contractId 合同id
     * @return float
     */
    public static function getContractRevenueInfoByRevenueId($revenueId)
    {
        $res = ContractRevenueEntity::find()->where(['revenue_id' => $revenueId])->orderBy('establish_time ASC')->one();
        return $res?$res:0;
    }

    /**
     * 根据时间获取收入数据
     * @param $beginTime
     * @param $endTime
     * @return array
     */
    public static function getRevenueInfoByTime($beginTime, $endTime)
    {
        $sql = "select distinct r.close_status, r.revenue_id, r.income_code, t.finance_type_name as type_name, r.amount, m.sign_date, m.contract_code as ContractCode, m.input_date, r.contract_id " .
            "from myscrm_contract_revenue as r " .
            "inner join myscrm_contract_manage as m on r.contract_id=m.contract_id " .
            "left join myscrm_buss_account_types as t on r.revenue_type=t.type_id " .
            "where m.is_cancelled=0 and m.contract_status=2 ";

        if (!empty($beginTime) && !empty($endTime)) {
            $sql .= "and m.input_date>:beginTime and m.input_date< :endTime";
        }
        $data = ContractRevenueEntity::getDb()->createCommand($sql, [':beginTime' => $beginTime, ':endTime' => $endTime])->queryAll();
        return $data;
    }

    public static function getRevenueInfoByRecognitionTime($recognition)
    {

        //当前激活结转期
        $recognitionDate = RevenueRecognitionDateRepository::getRecognitionDateNew();
        $thisRecognitionEnd = self::dateToYmd($recognitionDate['recognition_end']);

        $financeTypeName = '';
        if ($recognition === 'all') {
            $financeTypeName = "('" . implode("','", ['云客租用服务收入项', '云客增值服务收入项', '云客互联网服务收入项', '云客销售服务收入项']) . "')";
        }

        if ($recognition === 'date') {
            $financeTypeName = "('" . implode("','", ['云客租用服务收入项']) . "')";
        }

        if ($recognition === 'disposable') {
            $financeTypeName = "('" . implode("','", ['云客增值服务收入项']) . "')";
        }

        if ($recognition === 'ad') {
            $financeTypeName = "('" . implode("','", ['云客互联网服务收入项']) . "')";
        }

        $sql = "select distinct r.close_status, r.revenue_id, r.income_code, t.finance_type_name as type_name, r.amount, m.sign_date, m.contract_code as ContractCode, m.input_date, r.contract_id " .
            "from myscrm_contract_revenue as r " .
            "inner join myscrm_contract_manage as m on r.contract_id=m.contract_id " .
            "left join myscrm_buss_account_types as t on r.revenue_type=t.type_id " .
            "left join (SELECT revenue_id, count( revenue_id ) as this_recognition_times FROM myscrm_revenue_recognition WHERE recognition_end = :recognition_end GROUP BY revenue_id) AS temp_recognition on temp_recognition.revenue_id = r.revenue_id " .
            "where m.is_cancelled=0 and m.contract_status=2 and (r.close_status = 1) and t.finance_type_name in";

        $sql .= $financeTypeName;
        $sql .= "and (r.establish_time <= :recognition_end) ";
        $sql .= "AND (this_recognition_times < 1 or this_recognition_times is null) ";

        $data = ContractRevenueEntity::getDb()->createCommand($sql, [':recognition_end' => $thisRecognitionEnd])->queryAll();

        return $data;
    }

    /**
     * 修改收入编码
     * @param string $contractId 合同ID
     * @param string $incomeCode 收入编码
     * @return unknown
     */
    public static function updateIncomeCodeByContractId($contractId, $incomeCode)
    {

        $findResult = ContractRevenueEntity::findAll(["contract_id" => $contractId]);
        $sql = "UPDATE myscrm_contract_revenue set income_code = CONCAT(:incomeCode,SUBSTR(income_code,INSTR(income_code,'-SR-'))) WHERE contract_id = :contractId";
        $res = ContractRevenueEntity::getDb()->createCommand($sql, [':incomeCode' => $incomeCode, ':contractId' => $contractId])->execute();
        foreach ($findResult as $single) {
            $before = $single->getAttributes();
            $now = ContractRevenueEntity::findOne(['revenue_id' => $single->revenue_id])->getAttributes();
            IncomeItemLogRepository::add($before, $now, $res, IncomeItemLogRepository::OPERATE_EDIT);
        }
        return $res;
    }

    /**
     * 根据合同id删除
     * @param $contractId
     * @return int
     */
    public static function deleteByContractId($contractId)
    {
        /** @var MyscrmContractSyncDeleteDataRepository $contractSyncDeleteDataRepository */
        $contractSyncDeleteDataRepository = \Yii::createObject(MyscrmContractSyncDeleteDataRepository::className());

        $deleteData = ContractRevenueEntity::findAll(["contract_id" => $contractId]);

        $deleteResult = ContractRevenueEntity::deleteAll(["contract_id" => $contractId]);

        if ($deleteResult > 0) {
            foreach ($deleteData as $data) {
                $before = $data->getAttributes();
                $now = false;
                IncomeItemLogRepository::add($before, $now, $deleteResult, IncomeItemLogRepository::OPERATE_DELETE);
                $contractSyncDeleteDataRepository->add('myscrm_contract_revenue', 'revenue_id', $data['revenue_id']);
            }
        }

        return $deleteResult;
    }

    /**
     * 组建查找收入SQL
     * @param $where
     * @param $searchKey
     * @return array
     */
    private static function __buildGetRevenueWhereSql($where, $revenueModel)
    {
        //当前激活结转期
        $recognitionDate = RevenueRecognitionDateRepository::getRecognitionDateNew();

        $thisRecognitionBegin = self::dateToYmd($recognitionDate['recognition_begin']);
        $thisRecognitionEnd = self::dateToYmd($recognitionDate['recognition_end']);

        $params = [];

        if (isset($revenueModel->beginDate) && !empty($revenueModel->beginDate)) {
            $where = $where . ' and (revenue.begin_on >= :begin_on)';
            $params[':begin_on'] = $revenueModel->beginDate . ' 00:00:00';
        }

        if (isset($revenueModel->endDate) && !empty($revenueModel->endDate)) {
            $where = $where . ' and (revenue.end_on <= :end_on)';
            $params[':end_on'] = $revenueModel->endDate . ' 00:00:00';
        }

        if (isset($revenueModel->establishDate) && !empty($revenueModel->establishDate)) {
            $where = $where . ' and (revenue.establish_time = :establish_time)';
            $params[':establish_time'] = $revenueModel->establishDate . ' 00:00:00';
        }

        if (isset($revenueModel->closeStatus) && !empty($revenueModel->closeStatus) && $revenueModel->closeStatus === 'closed') {
            $where = $where . " and (revenue.close_status in (2,3,4))";
        }

        if (isset($revenueModel->closeStatus) && !empty($revenueModel->closeStatus) && $revenueModel->closeStatus === 'unclosed') {
            $where = $where . " and (revenue.close_status in (1))";
        }


        if (isset($revenueModel->type) && !empty($revenueModel->type) && $revenueModel->type === 'recognized') {
            $where = $where . " and (recognition.recognition_begin = :recognition_begin) and (recognition.recognition_end = :recognition_end)";
            $params[':recognition_begin'] = $thisRecognitionBegin . ' 00:00:00';
            $params[':recognition_end'] = $thisRecognitionEnd . ' 00:00:00';
        }

        if (isset($revenueModel->type) && !empty($revenueModel->type) && $revenueModel->type === 'unrecognized') {
            $where = $where . " and (revenue.establish_time <= :recognition_end)";
            $params[':recognition_begin'] = $thisRecognitionBegin . ' 00:00:00';
            $params[':recognition_end'] = $thisRecognitionEnd . ' 00:00:00';
        }

        if (isset($revenueModel->searchKey) && !empty($revenueModel->searchKey)) {
            $where = $where . " and (revenue.income_code like CONCAT('%', :income_code, '%'))";
            $params[':income_code'] = $revenueModel->searchKey;
        }

        if (isset($revenueModel->contractStatus) && $revenueModel->contractStatus === '0') {
            $where = $where . " and (manage.contract_status = :contract_status)";
            $params[':contract_status'] = 0;
        } else {
            $where = $where . " and (manage.contract_status = :contract_status)";
            $params[':contract_status'] = $revenueModel->contractStatus;
        }

        if (isset($revenueModel->isCancelled) && $revenueModel->isCancelled === '0') {
            $where = $where . " and (manage.is_cancelled = :is_cancelled)";
            $params[':is_cancelled'] = 0;
        } else {
            $where = $where . " and (manage.is_cancelled = :is_cancelled)";
            $params[':is_cancelled'] = $revenueModel->isCancelled;
        }
        $params[':recognition_begin'] = $thisRecognitionBegin . ' 00:00:00';
        $params[':recognition_end'] = $thisRecognitionEnd . ' 00:00:00';

        return ['where' => $where, 'params' => $params];
    }

    /**
     * 收入管理模块：获取收入列表信息，支持分页
     * @param string $searchKey 查询关键字
     * @param int $pageIndex 页索引
     * @param int $pageSize 页大小
     * @param string $pageSize 收入开始时间
     * @param string $pageSize 收入结束时间
     * @param string $pageSize 收入开通时间
     * @param int $pageSize 收入关闭状态
     * @return array PageResult
     */
    public static function getRevenueListByPage($revenueModel)
    {

        if ($revenueModel->type === 'recognized') {
            return self::getThisRecognitionRevenueList($revenueModel);
        }

        return self::getRevenueList($revenueModel);
    }

    /**
     * 获取分页本期已结转收入
     * @param $revenueModel
     * @return array
     */
    private static function getThisRecognitionRevenueList($revenueModel)
    {
        $where = '1=1';
        $whereSql = self::__buildGetRevenueWhereSql($where, $revenueModel);
        $whereSql['where'] .= ' AND ( `property`.`property_name` NOT LIKE "明源签约%" ) ';
        $query = new Query();
        $queryFilter = $query->select(
            'revenue.*,property.property_name,manage.income_amount,manage.sign_amount,manage.input_date,
            manage.contract_code,manage.sign_date,manage.contract_status,manage.is_cancelled,
            manage.customer_full_name,temp_recognition.recognition_times')
            ->from('myscrm_revenue_recognition AS recognition')
            ->leftJoin('myscrm_contract_revenue AS revenue', 'recognition.revenue_id = revenue.revenue_id')
            ->leftJoin('myscrm_contract_manage AS manage', 'manage.contract_id = revenue.contract_id')
            ->leftJoin('myscrm_contract_property AS property', 'manage.contract_property_id = property.property_id')
            ->leftJoin('( SELECT count( 1 ) AS recognition_times, revenue_id FROM myscrm_revenue_recognition WHERE recognition_end < "' . $whereSql['params'][':recognition_end'] . '" GROUP BY revenue_id ) temp_recognition', 'temp_recognition.revenue_id = revenue.revenue_id')
            ->where($whereSql['where'], $whereSql['params']);
        $total = $queryFilter->count("1", ContractEntity::getDb());
        $skip = ($revenueModel->pageIndex - 1) * $revenueModel->pageSize;//对性能有帮助 先查后分组
        $result = $queryFilter
            ->offset($skip)
            ->limit($revenueModel->pageSize)
            ->orderBy(['manage.input_date' => SORT_DESC])
            ->all(ContractEntity::getDb());

        return self::calculateThisRecognition($result, $total);
    }

    /**
     * 获取所有本期已本期收入
     * @param $revenueModel
     * @return array
     */
    private static function getAllThisRecognitionRevenueList($revenueModel)
    {
        $where = '1=1';
        $whereSql = self::__buildGetRevenueWhereSql($where, $revenueModel);
        $whereSql['where'] .= ' AND ( `property`.`property_name` NOT LIKE "明源签约%" ) ';
        $query = new Query();
        $queryFilter = $query->select(
            'revenue.*,property.property_name,manage.income_amount,manage.sign_amount,manage.input_date,
            manage.contract_code,manage.sign_date,manage.contract_status,manage.is_cancelled,
            manage.customer_full_name,temp_recognition.recognition_times')
            ->from('myscrm_revenue_recognition AS recognition')
            ->leftJoin('myscrm_contract_revenue AS revenue', 'recognition.revenue_id = revenue.revenue_id')
            ->leftJoin('myscrm_contract_manage AS manage', 'manage.contract_id = revenue.contract_id')
            ->leftJoin('myscrm_contract_property AS property', 'manage.contract_property_id = property.property_id')
            ->leftJoin('( SELECT count( 1 ) AS recognition_times, revenue_id FROM myscrm_revenue_recognition WHERE recognition_end < "' . $whereSql['params'][':recognition_end'] . '" GROUP BY revenue_id ) temp_recognition', 'temp_recognition.revenue_id = revenue.revenue_id')
            ->where($whereSql['where'], $whereSql['params']);
        $total = $queryFilter->count("1", ContractEntity::getDb());
        $result = $queryFilter
            ->orderBy(['manage.input_date' => SORT_DESC])
            ->all(ContractEntity::getDb());

        return self::calculateThisRecognition($result, $total);
    }

    /**
     * 获取所有本待确认收入
     * @param $revenueModel
     * @return array
     */
    private static function getAllRevenueList($revenueModel)
    {
        $where = '1=1';
        $whereSql = self::__buildGetRevenueWhereSql($where, $revenueModel);
        $whereSql['where'] = $whereSql['where'] . ' AND (this_recognition_times < :this_recognition_times or this_recognition_times is null)';
        $whereSql['params'][':this_recognition_times'] = 1;
        $query = new Query();
        $queryFilter = $query->select(
            'revenue.*,property.property_name,manage.income_amount,manage.sign_amount,manage.input_date,
                        manage.contract_code,manage.sign_date,manage.contract_status,manage.is_cancelled,
                        manage.customer_full_name,temp_recognition_total.recognition_times')
            ->from('myscrm_contract_revenue AS revenue')
            ->leftJoin('myscrm_contract_manage AS manage', 'manage.contract_id = revenue.contract_id')
            ->leftJoin('myscrm_contract_property AS property', 'manage.contract_property_id = property.property_id')
            ->leftJoin('(SELECT revenue_id, count( revenue_id ) as this_recognition_times FROM myscrm_revenue_recognition WHERE recognition_begin = :recognition_begin AND recognition_end = :recognition_end GROUP BY revenue_id) AS temp_recognition', 'temp_recognition.revenue_id = revenue.revenue_id')
            ->leftJoin('(SELECT revenue_id, count( revenue_id ) as recognition_times FROM myscrm_revenue_recognition GROUP BY revenue_id) AS temp_recognition_total', 'temp_recognition_total.revenue_id = revenue.revenue_id')
            ->where($whereSql['where'], $whereSql['params']);
        $total = $queryFilter->count("1", ContractEntity::getDb());
        $result = $queryFilter
            ->all(ContractEntity::getDb());

        return self::calculateThisRecognition($result, $total);
    }

    /**
     * 获取分页本期待本期收入
     * @param $revenueModel
     * @return array
     */
    private static function getRevenueList($revenueModel)
    {
        $where = '1=1';
        $whereSql = self::__buildGetRevenueWhereSql($where, $revenueModel);
        $whereSql['where'] = $whereSql['where'] . ' AND (this_recognition_times < :this_recognition_times or this_recognition_times is null)';
        $whereSql['params'][':this_recognition_times'] = 1;
        $query = new Query();
        $queryFilter = $query->select(
            'revenue.*,property.property_name,manage.income_amount,manage.sign_amount,manage.input_date,
                        manage.contract_code,manage.sign_date,manage.contract_status,manage.is_cancelled,
                        manage.customer_full_name,temp_recognition_total.recognition_times')
            ->from('myscrm_contract_revenue AS revenue')
            ->leftJoin('myscrm_contract_manage AS manage', 'manage.contract_id = revenue.contract_id')
            ->leftJoin('myscrm_contract_property AS property', 'manage.contract_property_id = property.property_id')
            ->leftJoin('(SELECT revenue_id, count( revenue_id ) as this_recognition_times FROM myscrm_revenue_recognition WHERE recognition_begin = :recognition_begin AND recognition_end = :recognition_end GROUP BY revenue_id) AS temp_recognition', 'temp_recognition.revenue_id = revenue.revenue_id')
            ->leftJoin('(SELECT revenue_id, count( revenue_id ) as recognition_times FROM myscrm_revenue_recognition GROUP BY revenue_id) AS temp_recognition_total', 'temp_recognition_total.revenue_id = revenue.revenue_id')
            ->where($whereSql['where'], $whereSql['params']);
        $total = $queryFilter->count("1", ContractEntity::getDb());
        $skip = ($revenueModel->pageIndex - 1) * $revenueModel->pageSize;//对性能有帮助 先查后分组
        $result = $queryFilter
            ->offset($skip)
            ->limit($revenueModel->pageSize)
            ->orderBy(['manage.input_date' => SORT_DESC])
            ->all(ContractEntity::getDb());

        return self::calculateThisRecognition($result, $total);
    }

    public static function exportRevenueList($revenueModel)
    {
        if ($revenueModel->type === 'recognized') {
            return self::getAllThisRecognitionRevenueList($revenueModel);
        }

        return self::getAllRevenueList($revenueModel);
    }

    private static function calculateThisRecognition($result, $total)
    {
        //当前激活结转期
        $recognitionDate = RevenueRecognitionDateRepository::getRecognitionDateNew();

        $thisRecognitionBegin = self::dateToYmd($recognitionDate['recognition_begin']);
        $thisRecognitionEnd = self::dateToYmd($recognitionDate['recognition_end']);

        if (0 === $total) {
            $items = [];
            return Helper::setPageResult($total, $items);
        } else {
            foreach ($result as $key => $item) {

                $revenueRecognitions = RevenueRecognitionRepository::getRevenueRecognitionListByRevenueId($item['revenue_id']);
//                $lastRecognizedList = RevenueRecognitionRepository::getRecognitionBeforeThisRecognitionEnd($item['revenue_id'],$thisRecognitionEnd);
                $totalRevenueRecognitionAmount = self::summaryAmount('recognition_amount', $revenueRecognitions);

                $equityBegin = self::dateToYmd($item['begin_on']);
                $equityEnd = self::dateToYmd($item['end_on']);
                $establishTime = self::dateToYmd($item['establish_time']);

                $financeTypeName = self::getRecognitionType($item['revenue_type'])['finance_type_name'];
                $scale = self::calculateScaleByRecognitionType($thisRecognitionBegin, $thisRecognitionEnd, $equityBegin, $equityEnd, $establishTime, $financeTypeName);
                $recognitionType = self::revenueTypeToRecognitionType($financeTypeName);

                //本期确认金额
                $totalCanRevenueAmount = self::totalCanRevenueAmount($item['amount'], $totalRevenueRecognitionAmount, $scale, $thisRecognitionEnd, $equityBegin, $equityEnd, $establishTime, $financeTypeName);

                $thisRecognitionAmount = self::getThisRecognitionAmount($item['revenue_id'], $thisRecognitionBegin, $thisRecognitionEnd);

                //微观考虑局部逻辑正确是否需要全局考虑历史数据 采取统算 当前方案非统算
                //统算逻辑 本期可结转金 = 当前结转期可以结转累计可以结转金额 - 累计已经结转金额
                $result[$key]['scale'] = $scale;
                $result[$key]['finance_type_name'] = $financeTypeName;
                $result[$key]['total_can_recognition_amount'] = $totalCanRevenueAmount;
                $result[$key]['this_recognition_amount'] = $thisRecognitionAmount;

                $result[$key]['this_recognition_begin'] = $thisRecognitionBegin;
                $result[$key]['this_recognition_end'] = $thisRecognitionEnd;

                $result[$key]['recognition_type'] = $recognitionType;
                //结转时间
                $result[$key]['revenue_recognition_date'] = empty($value['recognition_date']) ? '' : $value['recognition_date'];

                //即结转表中无本结转期间的记录的
                $thisRecognitionList = RevenueRecognitionRepository::getThisRecognitionList($item['revenue_id'], $thisRecognitionBegin, $thisRecognitionEnd);

                $result[$key]['this_recognition_status'] = empty($thisRecognitionList) ? '本期待确认' : '本期已确认';
                $result[$key]['total_revenue_recognition_amount'] = $totalRevenueRecognitionAmount;

                $paymentList = ContractPaymentRepository::getPaymentInfoByContractId($item['contract_id']);
                $invoicesList = InvoiceRepository::getInvoicesByContractId($item['contract_id']);
                $result[$key]['total_invoice_amount'] = self::summaryAmount('invoice_amount', $invoicesList);
                $result[$key]['total_payment_amount'] = self::summaryAmount('payment_amount', $paymentList);

                $result[$key]['revenue_close_status'] = in_array($item['close_status'], [2, 3, 4]) ? 'closed' : 'unclosed';

                //待确认金额 = 收入项金额 - 收入确认总金额
                $result[$key]['revenue_unrecognized_amount'] = floatval($item['amount']) - floatval($totalRevenueRecognitionAmount);

                //上期剩余，如果上一期存在结转数据，则该收入项为上期剩余 否则为本期新增 上期结转为0也算上期剩余
                //结转期是范围 如何判断哪些结转记录是当前激活结转期之前的结转记录
                $issueTotalRecognitionAmountAfterThis = RevenueRecognitionRepository::summaryRecognitionAmountAfterThis($item['revenue_id'], $thisRecognitionEnd);
                $lastIssueTotalRecognitionAmount = $totalRevenueRecognitionAmount - $issueTotalRecognitionAmountAfterThis;

                $result[$key]['last_total_revenue_recognition_amount'] = $lastIssueTotalRecognitionAmount;
                $result[$key]['revenue_source'] = (intval($result[$key]['recognition_times']) == 0) ? '本期新增' : '上期结转';

            }
            return Helper::setPageResult($total, $result);
        }
    }

    public static function totalCanRevenueAmount($amount, $totalRevenueRecognitionAmount, $scale, $thisRecognitionEnd, $equityBegin, $equityEnd, $establishTime, $financeTypeName)
    {
        if ($financeTypeName === self::YK_VALUE_ADDED_SERVICES_REVENUE) {

            if (empty($equityEnd) || empty($equityBegin) || empty($establishTime)) {//权益日期为空结转金额为0
                return 0;
            }

            if (strtotime($thisRecognitionEnd) > strtotime($equityEnd)) {//结转期大于租期末的，取收入项金额
                return round(floatval($amount) - round($totalRevenueRecognitionAmount, 3), 3);
            } else if (strtotime($thisRecognitionEnd) < strtotime($equityBegin)) {//结转期小于租期开始的，取0
                return 0;
            } else {
                return round(($amount * $scale) - $totalRevenueRecognitionAmount, 2);
            }
        } else if (($financeTypeName === self::YK_RENT_SERVICES_REVENUE) || ($financeTypeName === self::YK_INTERNET_SERVICES_REVENUE)) {//广告和增值都按一次性
            $recognitionAmount = empty($amount) ? 0 : ($amount * $scale) - $totalRevenueRecognitionAmount;//收入金额为0的情况一次性结转计算结转金额
            return round($recognitionAmount, 2);
        }


    }

    public static function calculateScaleByRecognitionType($thisRecognitionBegin, $thisRecognitionEnd, $equityBegin, $equityEnd, $establishTime, $financeTypeName)
    {
        $equityDays = self::dateCalculateDay($equityBegin, $equityEnd);

        //使用天数 = 当前日期 - 权益日期开始日期
        $usedDays = self::dateCalculateDay($equityBegin, $thisRecognitionEnd);
        $scale = 0;
        if ($financeTypeName === self::YK_VALUE_ADDED_SERVICES_REVENUE) {
            //权益日期开始时间在本期末之后的
            $scale = empty($equityDays) ? 0 : ($usedDays + 1) / ($equityDays + 1);

        } else if (($financeTypeName === self::YK_RENT_SERVICES_REVENUE) || ($financeTypeName === self::YK_INTERNET_SERVICES_REVENUE)) {//广告和增值都按一次性
            //一次性确认时 开通时间在本期范围内100%结转否则0%结转
            //$scale = (strtotime($establishTime)>=strtotime($thisRecognitionBegin) && strtotime($establishTime)<=strtotime($thisRecognitionEnd))?1:0;
            $scale = (strtotime($establishTime) <= strtotime($thisRecognitionEnd)) ? 1 : 0;

        }

        return $scale;
    }

    private static function revenueTypeToRecognitionType($financeTypeName)
    {
        $recognitionType = '';
        if ($financeTypeName === self::YK_VALUE_ADDED_SERVICES_REVENUE) {
            $recognitionType = '按照租期确认';
        } elseif ($financeTypeName === self::YK_RENT_SERVICES_REVENUE) {
            $recognitionType = '一次性确认';
        }

        return $recognitionType;
    }

    private static function summaryAmount($field, $list)
    {

        $amount = 0;

        foreach ($list as $item) {
            $amount += $item[$field];
        }

        return (string)sprintf("%.2f", $amount);
    }

    public static function getThisRecognitionAmount($revenueId, $recognitionBegin, $recognitionEnd)
    {

        $result = RevenueRecognitionRepository::getThisRecognitionList($revenueId, $recognitionBegin, $recognitionEnd);
        $thisRecognitionAmount = 0;
        foreach ($result as $item) {
            $thisRecognitionAmount += $item['recognition_amount'];
        }

        return $thisRecognitionAmount;
    }

    public static function getRecognitionType($typeId)
    {
        $query = new Query();
        return $query->select("*")->from('myscrm_buss_account_types')->where(['type_id' => $typeId])->one(ContractReceivableEntity::getDb());
    }

    private static function dateToYmd($date)
    {
        return substr($date, 0, -9);
    }

    private static function dateCalculateDay($begin, $end)
    {
        return (strtotime($end) - strtotime($begin)) / (3600 * 24);
    }

    public static function getIsNotClosedRevenueAll()
    {
        return ContractRevenueEntity::findAll(["close_status" => 1]);
    }

    public static function closeRevenueByRevenueId($revenueId, $type)
    {
        $entity = ContractRevenueEntity::find()->where(["revenue_id" => $revenueId])->one();
        $before = $entity ? $entity->getAttributes() : false;
        $entity->close_status = $type;
        $check = $entity->closeCheck();
        if (!$check) {
            return true;
        }
        $now = $entity ? $entity->getAttributes() : false;
        if ($entity->save()) {
            IncomeItemLogRepository::add($before, $now, 1, IncomeItemLogRepository::OPERATE_EDIT);
            return $entity->primaryKey;
        } else {
            IncomeItemLogRepository::add($before, $now, 0, IncomeItemLogRepository::OPERATE_EDIT);
            return false;
        }

    }

    public static function getRevenueByRevenueId($revenueId)
    {
        return ContractRevenueEntity::find()
            ->select("myscrm_contract_manage.erp_contract_id AS erp_contract_id,myscrm_contract_manage.erp_contract_code AS erp_contract_code,myscrm_buss_account_types.finance_type_name AS type_name,myscrm_contract_revenue.*")
            ->leftJoin('myscrm_buss_account_types', 'myscrm_buss_account_types.type_id = myscrm_contract_revenue.revenue_type')
            ->leftJoin('myscrm_contract_manage', 'myscrm_contract_manage.contract_id = myscrm_contract_revenue.contract_id')
            ->where(["revenue_id" => $revenueId])->one();
    }

}